//! 配置管理器
//! 
//! 提供动态配置管理功能，支持：
//! - 配置热更新
//! - 配置验证
//! - 配置版本管理
//! - 配置同步

use std::collections::HashMap;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use tokio::sync::RwLock;

use crate::error::{KernelError, Result};
use crate::event::{Event, EventBus, EventType};

/// 配置值类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConfigValue {
    String(String),
    Integer(i64),
    Float(f64),
    Boolean(bool),
    Array(Vec<ConfigValue>),
    Object(HashMap<String, ConfigValue>),
    Null,
}

/// 配置项
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigItem {
    /// 配置键
    pub key: String,
    /// 配置值
    pub value: ConfigValue,
    /// 配置描述
    pub description: Option<String>,
    /// 配置类型
    pub config_type: ConfigType,
    /// 是否需要重启
    pub requires_restart: bool,
    /// 验证规则
    pub validation_rules: Vec<ValidationRule>,
    /// 最后更新时间
    pub last_updated: chrono::DateTime<chrono::Utc>,
    /// 更新者
    pub updated_by: Option<String>,
}

/// 配置类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConfigType {
    /// 系统配置
    System,
    /// 插件配置
    Plugin(String),
    /// 数据源配置
    DataSource(String),
    /// 用户配置
    User(String),
    /// 临时配置
    Temporary,
}

/// 验证规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ValidationRule {
    /// 必填
    Required,
    /// 最小值
    MinValue(f64),
    /// 最大值
    MaxValue(f64),
    /// 最小长度
    MinLength(usize),
    /// 最大长度
    MaxLength(usize),
    /// 正则表达式
    Regex(String),
    /// 枚举值
    Enum(Vec<String>),
    /// 自定义验证
    Custom(String),
}

/// 配置变更记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigChange {
    /// 变更ID
    pub id: String,
    /// 配置键
    pub key: String,
    /// 旧值
    pub old_value: Option<ConfigValue>,
    /// 新值
    pub new_value: ConfigValue,
    /// 变更时间
    pub timestamp: chrono::DateTime<chrono::Utc>,
    /// 变更者
    pub changed_by: Option<String>,
    /// 变更原因
    pub reason: Option<String>,
}

/// 配置管理器
pub struct ConfigManager {
    /// 配置存储
    configs: Arc<RwLock<HashMap<String, ConfigItem>>>,
    /// 配置变更历史
    change_history: Arc<RwLock<Vec<ConfigChange>>>,
    /// 事件总线
    event_bus: Arc<EventBus>,
    /// 配置监听器
    listeners: Arc<RwLock<Vec<Arc<dyn ConfigListener>>>>,
}

/// 配置监听器接口
#[async_trait::async_trait]
pub trait ConfigListener: Send + Sync {
    /// 监听器ID
    fn id(&self) -> &str;
    
    /// 感兴趣的配置键模式
    fn interested_keys(&self) -> Vec<String>;
    
    /// 配置变更通知
    async fn on_config_changed(&self, change: &ConfigChange) -> Result<()>;
}

impl ConfigManager {
    /// 创建新的配置管理器
    pub fn new(event_bus: Arc<EventBus>) -> Self {
        Self {
            configs: Arc::new(RwLock::new(HashMap::new())),
            change_history: Arc::new(RwLock::new(Vec::new())),
            event_bus,
            listeners: Arc::new(RwLock::new(Vec::new())),
        }
    }
    
    /// 设置配置项
    pub async fn set_config(
        &self,
        key: String,
        value: ConfigValue,
        changed_by: Option<String>,
        reason: Option<String>,
    ) -> Result<()> {
        // 获取旧值
        let old_value = {
            let configs = self.configs.read().await;
            configs.get(&key).map(|item| item.value.clone())
        };
        
        // 验证新值
        if let Some(existing_item) = self.get_config_item(&key).await {
            self.validate_value(&value, &existing_item.validation_rules)?;
        }
        
        // 更新配置
        {
            let mut configs = self.configs.write().await;
            let item = configs.entry(key.clone()).or_insert_with(|| ConfigItem {
                key: key.clone(),
                value: ConfigValue::Null,
                description: None,
                config_type: ConfigType::System,
                requires_restart: false,
                validation_rules: Vec::new(),
                last_updated: chrono::Utc::now(),
                updated_by: None,
            });
            
            item.value = value.clone();
            item.last_updated = chrono::Utc::now();
            item.updated_by = changed_by.clone();
        }
        
        // 记录变更历史
        let change = ConfigChange {
            id: uuid::Uuid::new_v4().to_string(),
            key: key.clone(),
            old_value,
            new_value: value,
            timestamp: chrono::Utc::now(),
            changed_by,
            reason,
        };
        
        {
            let mut history = self.change_history.write().await;
            history.push(change.clone());
            
            // 限制历史记录数量
            if history.len() > 10000 {
                history.remove(0);
            }
        }
        
        // 通知监听器
        self.notify_listeners(&change).await?;
        
        // 发布配置变更事件
        let event = Event::new(
            EventType::ConfigChange,
            "config-manager".to_string(),
            serde_json::to_value(&change)?,
        );
        self.event_bus.publish(event).await?;
        
        tracing::debug!("配置已更新: {}", key);
        Ok(())
    }
    
    /// 获取配置值
    pub async fn get_config(&self, key: &str) -> Option<ConfigValue> {
        let configs = self.configs.read().await;
        configs.get(key).map(|item| item.value.clone())
    }
    
    /// 获取配置项
    pub async fn get_config_item(&self, key: &str) -> Option<ConfigItem> {
        let configs = self.configs.read().await;
        configs.get(key).cloned()
    }
    
    /// 获取所有配置
    pub async fn get_all_configs(&self) -> HashMap<String, ConfigItem> {
        let configs = self.configs.read().await;
        configs.clone()
    }
    
    /// 删除配置
    pub async fn remove_config(&self, key: &str, changed_by: Option<String>) -> Result<()> {
        let old_value = {
            let mut configs = self.configs.write().await;
            configs.remove(key).map(|item| item.value)
        };
        
        if let Some(old_val) = old_value {
            // 记录删除操作
            let change = ConfigChange {
                id: uuid::Uuid::new_v4().to_string(),
                key: key.to_string(),
                old_value: Some(old_val),
                new_value: ConfigValue::Null,
                timestamp: chrono::Utc::now(),
                changed_by,
                reason: Some("配置删除".to_string()),
            };
            
            {
                let mut history = self.change_history.write().await;
                history.push(change.clone());
            }
            
            // 通知监听器
            self.notify_listeners(&change).await?;
            
            tracing::debug!("配置已删除: {}", key);
        }
        
        Ok(())
    }
    
    /// 注册配置监听器
    pub async fn register_listener(&self, listener: Arc<dyn ConfigListener>) -> Result<()> {
        let mut listeners = self.listeners.write().await;
        listeners.push(listener);
        Ok(())
    }
    
    /// 取消注册配置监听器
    pub async fn unregister_listener(&self, listener_id: &str) -> Result<()> {
        let mut listeners = self.listeners.write().await;
        listeners.retain(|l| l.id() != listener_id);
        Ok(())
    }
    
    /// 获取配置变更历史
    pub async fn get_change_history(&self, limit: Option<usize>) -> Vec<ConfigChange> {
        let history = self.change_history.read().await;
        
        match limit {
            Some(n) => {
                let start = if history.len() > n { history.len() - n } else { 0 };
                history[start..].to_vec()
            },
            None => history.clone(),
        }
    }
    
    /// 批量设置配置
    pub async fn set_configs(
        &self,
        configs: HashMap<String, ConfigValue>,
        changed_by: Option<String>,
    ) -> Result<()> {
        for (key, value) in configs {
            self.set_config(key, value, changed_by.clone(), None).await?;
        }
        Ok(())
    }
    
    /// 验证配置值
    fn validate_value(&self, value: &ConfigValue, rules: &[ValidationRule]) -> Result<()> {
        for rule in rules {
            match rule {
                ValidationRule::Required => {
                    if matches!(value, ConfigValue::Null) {
                        return Err(KernelError::config("配置值不能为空"));
                    }
                },
                ValidationRule::MinValue(min) => {
                    if let Some(num) = self.extract_number(value) {
                        if num < *min {
                            return Err(KernelError::config(format!(
                                "配置值不能小于 {}", min
                            )));
                        }
                    }
                },
                ValidationRule::MaxValue(max) => {
                    if let Some(num) = self.extract_number(value) {
                        if num > *max {
                            return Err(KernelError::config(format!(
                                "配置值不能大于 {}", max
                            )));
                        }
                    }
                },
                ValidationRule::MinLength(min) => {
                    if let ConfigValue::String(s) = value {
                        if s.len() < *min {
                            return Err(KernelError::config(format!(
                                "配置值长度不能小于 {}", min
                            )));
                        }
                    }
                },
                ValidationRule::MaxLength(max) => {
                    if let ConfigValue::String(s) = value {
                        if s.len() > *max {
                            return Err(KernelError::config(format!(
                                "配置值长度不能大于 {}", max
                            )));
                        }
                    }
                },
                ValidationRule::Enum(allowed_values) => {
                    if let ConfigValue::String(s) = value {
                        if !allowed_values.contains(s) {
                            return Err(KernelError::config(format!(
                                "配置值必须是以下之一: {:?}", allowed_values
                            )));
                        }
                    }
                },
                _ => {
                    // 其他验证规则的实现
                }
            }
        }
        Ok(())
    }
    
    /// 提取数值
    fn extract_number(&self, value: &ConfigValue) -> Option<f64> {
        match value {
            ConfigValue::Integer(i) => Some(*i as f64),
            ConfigValue::Float(f) => Some(*f),
            _ => None,
        }
    }
    
    /// 通知监听器
    async fn notify_listeners(&self, change: &ConfigChange) -> Result<()> {
        let listeners = self.listeners.read().await;
        
        for listener in listeners.iter() {
            // 检查监听器是否对此配置键感兴趣
            let interested = listener.interested_keys().iter().any(|pattern| {
                // 简单的模式匹配，支持通配符 *
                if pattern.contains('*') {
                    let prefix = pattern.trim_end_matches('*');
                    change.key.starts_with(prefix)
                } else {
                    &change.key == pattern
                }
            });
            
            if interested {
                if let Err(e) = listener.on_config_changed(change).await {
                    tracing::error!("配置监听器执行失败 {}: {}", listener.id(), e);
                }
            }
        }
        
        Ok(())
    }
}

impl ConfigValue {
    /// 转换为字符串
    pub fn as_string(&self) -> Option<String> {
        match self {
            ConfigValue::String(s) => Some(s.clone()),
            _ => None,
        }
    }
    
    /// 转换为整数
    pub fn as_integer(&self) -> Option<i64> {
        match self {
            ConfigValue::Integer(i) => Some(*i),
            _ => None,
        }
    }
    
    /// 转换为浮点数
    pub fn as_float(&self) -> Option<f64> {
        match self {
            ConfigValue::Float(f) => Some(*f),
            ConfigValue::Integer(i) => Some(*i as f64),
            _ => None,
        }
    }
    
    /// 转换为布尔值
    pub fn as_boolean(&self) -> Option<bool> {
        match self {
            ConfigValue::Boolean(b) => Some(*b),
            _ => None,
        }
    }
    
    /// 检查是否为空
    pub fn is_null(&self) -> bool {
        matches!(self, ConfigValue::Null)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::event::EventBus;
    
    #[tokio::test]
    async fn test_config_manager() {
        let event_bus = Arc::new(EventBus::new());
        let config_manager = ConfigManager::new(event_bus);
        
        // 设置配置
        config_manager.set_config(
            "test.key".to_string(),
            ConfigValue::String("test_value".to_string()),
            Some("test_user".to_string()),
            Some("测试配置".to_string()),
        ).await.unwrap();
        
        // 获取配置
        let value = config_manager.get_config("test.key").await;
        assert!(matches!(value, Some(ConfigValue::String(s)) if s == "test_value"));
        
        // 更新配置
        config_manager.set_config(
            "test.key".to_string(),
            ConfigValue::String("updated_value".to_string()),
            Some("test_user".to_string()),
            Some("更新配置".to_string()),
        ).await.unwrap();
        
        // 检查变更历史
        let history = config_manager.get_change_history(None).await;
        assert_eq!(history.len(), 2);
        
        // 删除配置
        config_manager.remove_config("test.key", Some("test_user".to_string())).await.unwrap();
        
        // 检查配置是否已删除
        let value = config_manager.get_config("test.key").await;
        assert!(value.is_none());
    }
}
